import 'package:flutter/material.dart';
import 'package:scrollable_positioned_list/scrollable_positioned_list.dart';
import 'package:t3_data_service/biz_data_source/map/address/city_pick/city_pick.dart';
import 'city_list_view.dart';
import 'index_bar.dart';

/// CityPickView
class CityPickView extends StatefulWidget {
  final List<T3IndexModel> data;
  final int itemCount;
  final IndexedWidgetBuilder itemBuilder;

  final ScrollPhysics? physics;
  final EdgeInsets? padding;

  final IndexedWidgetBuilder? susItemBuilder;
  final double susItemHeight;
  final Offset? susPosition;

  final List<String> indexBarData;
  final double indexBarWidth;
  final double? indexBarHeight;
  final double indexBarItemHeight;

  final AlignmentGeometry indexBarAlignment;
  final EdgeInsetsGeometry? indexBarMargin;
  final IndexBarOptions indexBarOptions;

  const CityPickView({
    Key? key,
    required this.data,
    required this.itemCount,
    required this.itemBuilder,
    this.physics,
    this.padding,
    this.susItemBuilder,
    this.susItemHeight = 55.0,
    this.susPosition,
    this.indexBarData = kIndexBarData,
    this.indexBarWidth = kIndexBarWidth,
    this.indexBarHeight,
    this.indexBarItemHeight = kIndexBarItemHeight,
    this.indexBarAlignment = Alignment.centerRight,
    this.indexBarMargin,
    this.indexBarOptions = const IndexBarOptions(),
  }) : super(key: key);

  @override
  _CityPickViewState createState() => _CityPickViewState();
}

class _CityPickViewState extends State<CityPickView> {
  ItemScrollController itemScrollController = ItemScrollController();
  ItemPositionsListener itemPositionsListener = ItemPositionsListener.create();

  IndexBarDragListener dragListener = IndexBarDragListener.create();
  final IndexBarController indexBarController = IndexBarController();

  String selectTag = '';

  @override
  void initState() {
    super.initState();

    dragListener.dragDetails.addListener(_valueChanged);
    if (widget.indexBarOptions.selectItemDecoration != null) {
      itemPositionsListener.itemPositions.addListener(_positionsChanged);
    }
  }

  @override
  void dispose() {
    super.dispose();
    dragListener.dragDetails.removeListener(_valueChanged);
    if (widget.indexBarOptions.selectItemDecoration != null) {
      itemPositionsListener.itemPositions.removeListener(_positionsChanged);
    }
  }

  int _getIndex(String tag) {
    for (int i = 0; i < widget.itemCount; i++) {
      T3IndexModel indexModel = widget.data[i];
      if (tag == indexModel.getIndexTag()) {
        return i;
      }
    }
    return -1;
  }

  void _scrollTopIndex(String tag) {
    int index = _getIndex(tag);
    if (index != -1) {
      itemScrollController.scrollTo(
          index: index,
          duration: const Duration(milliseconds: 250),
          curve: Curves.easeInOut);
    }
  }

  void _valueChanged() {
    IndexBarDragDetails details = dragListener.dragDetails.value;
    String tag = details.tag!;
    if (details.action == IndexBarDragDetails.actionDown ||
        details.action == IndexBarDragDetails.actionUpdate) {
      selectTag = tag;
      _scrollTopIndex(tag);
    }
  }

  void _positionsChanged() {
    Iterable<ItemPosition> positions =
        itemPositionsListener.itemPositions.value;
    if (positions.isNotEmpty) {
      ItemPosition itemPosition = positions
          .where((ItemPosition position) => position.itemTrailingEdge > 0)
          .reduce((ItemPosition min, ItemPosition position) =>
              position.itemTrailingEdge < min.itemTrailingEdge
                  ? position
                  : min);
      int index = itemPosition.index;
      String tag = widget.data[index].getIndexTag();
      if (selectTag != tag) {
        selectTag = tag;
        indexBarController.updateTagIndex(tag);
      }
    }
  }

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: [
        CityListView(
          data: widget.data,
          itemCount: widget.itemCount,
          itemBuilder: widget.itemBuilder,
          itemScrollController: itemScrollController,
          itemPositionsListener: itemPositionsListener,
          susItemBuilder: widget.susItemBuilder,
          susItemHeight: widget.susItemHeight,
          susPosition: widget.susPosition,
          padding: widget.padding,
          physics: widget.physics,
        ),
        Align(
          alignment: widget.indexBarAlignment,
          child: IndexBar(
            data: widget.indexBarData,
            width: widget.indexBarWidth,
            height: widget.indexBarHeight,
            itemHeight: widget.indexBarItemHeight,
            margin: widget.indexBarMargin,
            indexBarDragListener: dragListener,
            options: widget.indexBarOptions,
            controller: indexBarController,
          ),
        ),
      ],
    );
  }
}
